<template>
  <div class="hello">
    <el-button type="success" class="btn" @click="ch">撤回</el-button>
    <el-button type="success" class="btn_1" @click="type = 'level'">水平线</el-button>
    <el-button type="success" class="btn_2" @click="type = 'vertical'">垂直线</el-button>
    <el-button type="success" class="btn_3" @click="save">保存</el-button>
    <el-button type="success" class="btn_4" @click="createTable">生成表格</el-button>
    <el-button type="success" class="btn_5" @click="clear">清除</el-button>
    <el-button type="success" class="btn_6" @click="downloadFile">导出</el-button>
    <img src="../assets/001.jpg" ref="pic" style="display:none">
    <canvas id="myCanvas" ref="myCanvas" @mousedown="mousedown" @mouseup="mouseup" @mousemove="mousemove" @dblclick="doubleClick"></canvas>
  </div>
</template>

<script>
export default {
  data () {
    return {
      startx: 0,
      starty: 0,
      endx: 0,
      endy: 0,
      linePositionList: [],
      lineSize: 5,
      lineColor: 'red',
      flag: false,
      lastImageData: null, // 快照
      type: 'level', // vertical（垂直）|| level（水平）
      canvas: null,
      context: null,
      tablePosition: [],
      loading: false
    }
  },
  mounted() {
    this.createCanvas()
  },
  methods: {
    exportWs() {
        return this.$axios({
            method: 'post',
            url: '/api/v1/export',
            responseType: "blob",
            data: {
                'id' : 1
            }
        })
    },
    downloadFile () {
      this.exportWs().then((res) => {
          let objectUrl = URL.createObjectURL(new Blob([res.data], {
            type: 'application/msword'
          }))
          let a = document.createElement('a')
          a.href = objectUrl
          a.download = 'sss'
          a.click()
      })
    },
    clear() {
      this.linePositionList = []
      this.createLine()
    },
    createCanvas() {
      this.$refs.pic.onload = () => {
        this.canvas = this.$refs.myCanvas
        this.canvas.width = this.$refs.pic.width
        this.canvas.height = this.$refs.pic.height
        this.context = this.canvas.getContext('2d')
        //设置线条颜色，必须放在绘制之前
        this.context.strokeStyle = this.lineColor;
        // 线宽设置，必须放在绘制之前
        this.context.lineWidth = this.lineSize;
        this.drawPic()
      }
    },
    createTable() {
      this.loading = true
      this.$axios.get('/static/result.json').then(res => {
        this.tablePosition = res.data.trs
        // 横线的坐标
        this.setLevelLine()
        // 竖线的坐标
        this.setVerticalLine()
        this.createLine()
        this.loading = false
      })
    },
    setLevelLine() {
      for (let i = 0; i < this.tablePosition.length; i++) {
        let item = this.tablePosition[i].coordinate
        // 如果是第一行的话画上下两行线，否则的话只画下面的线即可
        if (i === 0) {
          let position = {
            startx: item.upperLeft_x,
            starty: item.upperLeft_y,
            endx: item.upperRight_x,
            endy: item.upperRight_y
          }
          this.linePositionList.push(position)
        }
        let position = {
          startx: item.lowerLeft_x,
          starty: item.lowerLeft_y,
          endx: item.lowerRight_x,
          endy: item.lowerRight_y
        }
        this.linePositionList.push(position)
      }
    },
    setVerticalLine() {
      for (let i = 0; i < this.tablePosition[0].tds.length; i++) {
        // 第一行第i个表格
        let first =  this.tablePosition[0].tds[i].coordinate
        // 最后一行第i个表格
        let last =  this.tablePosition[this.tablePosition.length - 1].tds[i].coordinate
        // 如果是第一列的话画左右两列线，否则的话只画右面的线即可
        if (i === 0) {
          let position = {
            startx: first.upperLeft_x,
            starty: first.upperLeft_y,
            endx: last.lowerLeft_x,
            endy: last.lowerLeft_y
          }
          this.linePositionList.push(position)
        }
        let position = {
          startx: first.upperRight_x,
          starty: first.upperRight_y,
          endx: last.lowerRight_x,
          endy: last.lowerRight_y
        }
        this.linePositionList.push(position)
      }
    },
    save() {
      let img = this.canvas.toDataURL('image/png');
      let param = {
        imgBase64: img,
        wjbh: '12b7690c00524b2f8e5148299743ab3f',
        bmsah: '修检起诉受[2015]52012300189号'
      }
      this.$axios.post('/api/saveImg',param).then(res => {
        if (res.status === 200) {
          this.$message({
            message: '保存成功',
            type: 'success'
          });
        }
      }).catch(err => {
        console.log(err)
      })
    },
    ch() {
      if (this.linePositionList.length === 0) {
        this.$message({
          message: '当前没有操作可以撤回',
          type: 'warning'
        });
        return
      }
      // 清除画布内容
      this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
      if (this.linePositionList.length > 0) {
        this.linePositionList.pop()
        this.createLine()
      }
    },
    mousedown(e){
      this.flag = true;
      if (this.type === 'level') {
        // 鼠标落下时的X
        this.startx = e.offsetX;
        this.endx = this.startx;
        // 鼠标落下时的Y
        this.starty = e.offsetY + this.lineSize / 2;
        this.endy = this.starty;
      } else {
        // 鼠标落下时的X
        this.startx = e.offsetX + this.lineSize / 2;
        this.endx = this.startx;
        // 鼠标落下时的Y
        this.starty = e.offsetY;
        this.endy = this.starty;
      }
    },
    mousemove(e){
      this.drawRect(e);
    },
    drawRect(e){
      if(this.flag){
        // 清除画布内容
        this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
        this.drawPic()
        if (this.lastImageData) {
          this.context.putImageData(this.lastImageData, 0, 0)
        }
        // 开始一次新的绘制
        this.context.beginPath();
        // 起点坐标
        this.context.moveTo(this.startx, this.starty);
        if (this.type === 'level') {
          this.endx = e.offsetX
          this.endy = this.starty
        } else {
          this.endx = this.startx
          this.endy = e.offsetY
        }
        // 终点坐标
        this.context.lineTo(this.endx, this.endy);
        // 沿着坐标点顺序的路径绘制直线
        this.context.stroke();
        //关闭当前的绘制路径
        this.context.closePath();
      }
    },
    mouseup(){
      this.flag = false;
      if (!(this.startx === this.endx && this.endy === this.starty)) {
        let position = {
          startx: this.startx,
          starty: this.starty,
          endx: this.endx,
          endy: this.endy
        }
        this.linePositionList.push(position)
        this.createLine()
      }
    },
    drawPic() {
      if (this.$refs.pic) {
        this.context.drawImage(this.$refs.pic, 0, 0)
      }
    },
    createLine() {
      // 清除画布内容
      this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
      this.drawPic()
      for(const item of this.linePositionList) {
        this.context.beginPath();
        this.context.moveTo(item.startx, item.starty);
        this.context.lineTo(item.endx, item.endy);
        this.context.stroke();
        this.context.closePath();
      }
      this.lastImageData = this.context.getImageData(0, 0, this.canvas.width,this.canvas.height)
    },
    doubleClick(e) {
      for (const item of this.linePositionList) {
          let position = this.getPointPositionLevel(item)
          let check = this.isInside(position.x1,position.y1,position.x1,position.y4,position.x4,position.y4,position.x4,position.y1,e.offsetX,e.offsetY)
          if (!check) {
            position = this.getPointPositionVertical(item)
            check = this.isInside(position.x1,position.y1,position.x1,position.y4,position.x4,position.y4,position.x4,position.y1,e.offsetX,e.offsetY)
          }
          if (check) {
            this.$set(item, 'del', true)
            break
          }
        }
      this.linePositionList = this.linePositionList.filter(item => item.del !== true)
      this.createLine()
    },
    // 思路：四个点A、B、C、D（按逆时针顺序）的坐标，求点P是否在ABCD所围成的四边形内，可以通过向量叉乘的方法实现
    isInside(x1, y1, x2, y2, x3, y3, x4, y4, x, y) {
      let a = (x2 - x1)*(y - y1) - (y2 - y1)*(x - x1)
      let b = (x3 - x2)*(y - y2) - (y3 - y2)*(x - x2)
      let c = (x4 - x3)*(y - y3) - (y4 - y3)*(x - x3)
      let d = (x1 - x4)*(y - y4) - (y1 - y4)*(x - x4)
      return (a > 0 && b > 0 && c > 0 && d > 0) || (a < 0 && b < 0 && c < 0 && d < 0)

    },
    getPointPositionLevel(item) {
      let position = {
        x1: 0,
        y1: 0,
        x4: 0,
        y4: 0
      }
      let startx = item.startx
      let starty = item.starty + this.lineSize / 2
      let endx = item.endx
      let endy = item.endy + this.lineSize / 2
      if (startx > endx) {
        position.x1 = endx
        position.y1 = endy - this.lineSize
        position.x4 = startx
        position.y4 = starty
      } else {
        position.x1 = startx
        position.y1 = starty - this.lineSize
        position.x4 = endx
        position.y4 = endy
      }
    return position
    },
    getPointPositionVertical(item) {
      let position = {
        x1: 0,
        y1: 0,
        x4: 0,
        y4: 0
      }
      let startx = item.startx + this.lineSize / 2
      let starty = item.starty
      let endx = item.endx + this.lineSize / 2
      let endy = item.endy
      if (starty > endy) {
        position.x1 = endx - this.lineSize
        position.y1 = endy
        position.x4 = position.x1 + this.lineSize
        position.y4 = starty
      } else {
        position.x1 = startx - this.lineSize
        position.y1 = starty
        position.x4 = position.x1 + this.lineSize
        position.y4 = endy
      }
      return position
    }
  }
}
</script>
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
.hello{
  width: 100%;
}
#myCanvas{
  position: absolute;
  border: 1px solid blue;
}
.btn{
  position: absolute;
  left: 10px;
  z-index: 999;
}
.btn_1{
  position: absolute;
  left: 100px;
  z-index: 999;
}
.btn_2{
  position: absolute;
  left: 200px;
  z-index: 999;
}
.btn_3{
  position: absolute;
  left: 300px;
  z-index: 999;
}
  .btn_4{
    position: absolute;
    left: 400px;
    z-index: 999;
  }
  .btn_5{
    position: absolute;
    left: 550px;
    z-index: 999;
  }
  .btn_6{
    position: absolute;
    left: 650px;
    z-index: 999;
  }
</style>
